package org.example.demo.controller;

import org.example.demo.model.CommonResponse;
import org.example.demo.model.bo.EducationCertificationCreateStudentRecordInputBO;
import org.example.demo.service.EducationCertificationService;
import org.example.demo.service.StudentStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/api")
public class StudentController {

    @Autowired
    private EducationCertificationService educationCertificationService;

    @Autowired
    private StudentStorageService studentStorageService;

    @PostMapping("/students")
    public CommonResponse createStudent(@RequestBody Map<String, String> studentData) {
        try {
            EducationCertificationCreateStudentRecordInputBO inputBO = new EducationCertificationCreateStudentRecordInputBO();
            inputBO.setStudentId(studentData.get("studentId"));
            inputBO.setName(studentData.get("name"));
            inputBO.setEducation(studentData.get("education"));
            inputBO.setGraduationYear(new BigInteger(studentData.get("graduationYear")));

            educationCertificationService.createStudentRecord(inputBO);
            
            // 创建成功后保存学生信息
            Map<String, Object> student = new HashMap<>();
            student.put("studentId", studentData.get("studentId"));
            student.put("name", studentData.get("name"));
            student.put("education", studentData.get("education"));
            student.put("graduationYear", studentData.get("graduationYear"));
            
            studentStorageService.addStudent(student);
            return CommonResponse.ok(student);
        } catch (Exception e) {
            return CommonResponse.error(e.getMessage());
        }
    }

    @GetMapping("/students")
    public CommonResponse getStudents() {
        try {
            System.out.println("\n======== 开始获取学生信息 ========");
            long startTime = System.currentTimeMillis();
            
            if (educationCertificationService == null) {
                System.err.println("区块链服务未初始化");
                return CommonResponse.error("区块链服务未初始化");
            }

            // 最终结果列表
            List<Map<String, Object>> resultStudents = new ArrayList<>();
            Set<String> processedIds = new HashSet<>(); // 防止重复
            
            // 1. 从证书中获取学生地址和信息
            System.out.println("\n【1. 从证书获取学生】");
            List<Map<String, Object>> studentsFromCerts = getStudentsFromCertificates();
            for (Map<String, Object> student : studentsFromCerts) {
                String studentId = (String) student.get("studentId");
                if (!processedIds.contains(studentId)) {
                    processedIds.add(studentId);
                    resultStudents.add(student);
                    System.out.println("  从证书获取学生: " + student.get("name"));
                }
            }
            System.out.println("  从证书获取学生数: " + studentsFromCerts.size());
            
            // 2. 检查已知的固定地址，但不创建新学生
            System.out.println("\n【2. 检查已知固定地址】");
            List<Map<String, Object>> fixedStudents = getExistingStudentsFromFixedAddresses();
            for (Map<String, Object> student : fixedStudents) {
                String studentId = (String) student.get("studentId");
                if (!processedIds.contains(studentId)) {
                    processedIds.add(studentId);
                    resultStudents.add(student);
                    System.out.println("  从固定地址获取学生: " + student.get("name"));
                }
            }
            System.out.println("  从固定地址获取学生数: " + fixedStudents.size());
            
            // 3. 查询本地存储的学生，验证是否在链上存在
            System.out.println("\n【3. 验证本地存储学生】");
            List<Map<String, Object>> localStudents = studentStorageService.getAllStudents();
            int validLocalCount = 0;
            for (Map<String, Object> student : localStudents) {
                String studentId = (String) student.get("studentId");
                if (!processedIds.contains(studentId)) {
                    boolean verified = verifyStudentOnChain(studentId);
                    if (verified) {
                        processedIds.add(studentId);
                        resultStudents.add(student);
                        System.out.println("  本地学生存在于链上: " + student.get("name"));
                        validLocalCount++;
                    }
                }
            }
            System.out.println("  验证通过的本地学生数: " + validLocalCount);
            
            long endTime = System.currentTimeMillis();
            System.out.println("\n【总结】获取到链上学生数据: " + resultStudents.size() + "个，耗时: " + (endTime - startTime) + "ms");
            for (Map<String, Object> student : resultStudents) {
                System.out.println("学生ID: " + student.get("studentId") + 
                                  ", 姓名: " + student.get("name") + 
                                  ", 学历: " + student.get("education"));
            }
            
            System.out.println("======== 学生信息获取完成 ========\n");
            return CommonResponse.ok(resultStudents);
            
        } catch (Exception e) {
            System.err.println("获取学生数据失败: " + e.getMessage());
            e.printStackTrace();
            return CommonResponse.error("获取学生数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 从证书中获取学生信息
     */
    private List<Map<String, Object>> getStudentsFromCertificates() {
        List<Map<String, Object>> students = new ArrayList<>();
        Set<String> processedAddresses = new HashSet<>();
        
        try {
            // 尝试获取更多证书ID
            for (int i = 1; i <= 50; i++) { // 增加获取范围到50个证书
                try {
                    // 获取完整证书信息，而不仅仅是证书属性
                    org.example.demo.model.bo.EducationCertificationCertificatesInputBO certInput = 
                        new org.example.demo.model.bo.EducationCertificationCertificatesInputBO(BigInteger.valueOf(i));
                    
                    // 获取证书完整记录
                    org.fisco.bcos.sdk.transaction.model.dto.CallResponse certResponse = 
                        educationCertificationService.certificates(certInput);
                    
                    if (certResponse != null && certResponse.getValues() != null) {
                        String certData = certResponse.getValues();
                        if (certData.startsWith("[") && certData.endsWith("]")) {
                            certData = certData.substring(1, certData.length() - 1);
                        }
                        
                        // 打印原始数据以便调试
                        System.out.println("证书 #" + i + " 原始数据: " + certData);
                        
                        // 分割字段并打印以便清楚看到结构
                        String[] fields = certData.split(",");
                        for (int j = 0; j < Math.min(fields.length, 8); j++) {
                            System.out.println("  字段 " + j + ": [" + fields[j].trim() + "]");
                        }
                        
                        // 获取学生地址，通常是第二个字段 (索引1)
                        if (fields.length > 1) {
                            String studentAddress = fields[1].trim();
                            System.out.println("  提取学生地址: " + studentAddress);
                            
                            // 确保不重复处理同一个地址
                            if (!processedAddresses.contains(studentAddress) && 
                                !studentAddress.equals("0x0000000000000000000000000000000000000000")) {
                                
                                processedAddresses.add(studentAddress);
                                System.out.println("  从证书 " + i + " 获取到学生地址: " + studentAddress);
                                
                                // 获取学生信息
                                Map<String, Object> student = getStudentRecord(studentAddress);
                                if (student != null) {
                                    students.add(student);
                                    System.out.println("  成功获取到证书对应的学生: " + student.get("name"));
                                } else {
                                    // 如果学生记录不存在但地址有效，创建一个默认记录
                                    Map<String, Object> defaultStudent = new HashMap<>();
                                    defaultStudent.put("studentId", studentAddress);
                                    defaultStudent.put("name", "未命名学生 #" + i);
                                    defaultStudent.put("education", "未知学历");
                                    defaultStudent.put("graduationYear", "0");
                                    students.add(defaultStudent);
                                    System.out.println("  为地址 " + studentAddress + " 创建默认学生记录");
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    // 这个证书ID可能不存在，继续下一个
                    if (e.getMessage() != null && e.getMessage().contains("Certificate does not exist")) {
                        System.out.println("  证书 #" + i + " 不存在");
                    } else {
                        System.err.println("  获取证书 #" + i + " 失败: " + e.getMessage());
                    }
                }
            }
            
            System.out.println("  总共从证书中获取到 " + students.size() + " 个学生");
        } catch (Exception e) {
            System.err.println("  获取证书信息失败: " + e.getMessage());
        }
        
        return students;
    }
    
    /**
     * 验证学生是否存在于链上
     */
    private boolean verifyStudentOnChain(String address) {
        try {
            Map<String, Object> student = getStudentRecord(address);
            return student != null;
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 从已知的固定地址获取现有学生
     */
    private List<Map<String, Object>> getExistingStudentsFromFixedAddresses() {
        List<Map<String, Object>> students = new ArrayList<>();
        List<String> addresses = new ArrayList<>();
        
        // 最常见的地址格式 - 只检查，不创建
        addresses.add("0x0000000000000000000000000000000000000000"); // 全0地址
        addresses.add("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); // 全F地址
        addresses.add("0x1111111111111111111111111111111111111111"); // 全1地址
        
        // 合约部署和管理地址
        addresses.add("0x3486f788b1def23078d0e1108323d3c3cd785402"); // 合约地址
        addresses.add("0x8c17cf316c1063ab6c89df875e96c9f0f5b2f744"); // 管理地址
        
        // 简单序号地址 - 增加数量到30个
        for (int i = 1; i <= 30; i++) {
            addresses.add("0x" + String.format("%040x", i));
        }
        
        // 添加特定序号的地址
        for (int i = 1; i <= 10; i++) {
            addresses.add("0x000000000000000000000000000000000000000" + i);
        }
        
        // 添加一些可能的前端生成的地址格式
        addresses.add("0x8c17cf316c1063ab6c89df875e96c9f0f5b2f744"); // 默认管理地址
        addresses.add("0x1234567890123456789012345678901234567890"); // 测试地址
        
        // 打印地址列表以便调试
        System.out.println("  尝试检查 " + addresses.size() + " 个固定地址");
        
        // 处理每个地址 - 只检查，不创建
        int foundCount = 0;
        for (String address : addresses) {
            try {
                // 只尝试获取学生记录，不创建新的
                Map<String, Object> student = getStudentRecord(address);
                if (student != null) {
                    students.add(student);
                    System.out.println("  找到已存在的学生: " + student.get("name") + ", ID: " + student.get("studentId"));
                    foundCount++;
                }
            } catch (Exception e) {
                // 忽略错误，继续下一个地址
            }
        }
        
        System.out.println("  从固定地址中找到 " + foundCount + " 个学生");
        return students;
    }
    
    /**
     * 获取学生记录
     */
    private Map<String, Object> getStudentRecord(String address) {
        try {
            org.example.demo.model.bo.EducationCertificationGetStudentRecordInputBO inputBO = 
                new org.example.demo.model.bo.EducationCertificationGetStudentRecordInputBO();
            inputBO.set_studentId(address);
            
            // 查询学生记录
            org.fisco.bcos.sdk.transaction.model.dto.CallResponse response = 
                educationCertificationService.getStudentRecord(inputBO);
            
            if (response != null && response.getValues() != null) {
                // 解析返回值
                String rawData = response.getValues();
                
                // 去除[]
                if (rawData.startsWith("[") && rawData.endsWith("]")) {
                    rawData = rawData.substring(1, rawData.length() - 1);
                }
                
                // 分割字段
                String[] fields = rawData.split(",");
                if (fields.length >= 3) {
                    Map<String, Object> student = new HashMap<>();
                    student.put("studentId", address);
                    student.put("name", fields[0].trim());
                    student.put("education", fields[1].trim());
                    student.put("graduationYear", fields[2].trim());
                    return student;
                } else {
                    System.err.println("  学生数据格式不正确: " + rawData);
                }
            }
            
            return null;
        } catch (Exception e) {
            // 常见的"不存在"错误，不打印堆栈
            if (e.getMessage() != null && e.getMessage().contains("Student record does not exist")) {
                return null;
            }
            
            // 其他错误
            System.err.println("获取学生 " + address + " 记录失败: " + e.getMessage());
            return null;
        }
    }
} 